package de.hsb.ai.agent.misterx.minimax;

import jade.core.AID;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.hsb.ai.agent.misterx.brain.Brain;

/**
 * Minimax Node
 * @author Dennis
 *
 */
public class Node {

	public int _mrXState; //Node auf dem sich MrX befindet
	public int _action; //
	
	public int _cost = 0; //Utility-Wert //Gewichtung
	public Node _parent;
	public int _depth;
	
	public boolean _terminalNode = false;
	
	public ArrayList<Node> _childs = new ArrayList<Node>();;
	public HashMap<AID, Integer> _detectiveStates = new HashMap<AID, Integer>();
	public Map<Integer, Integer> _tickets;
	
	
	public Node() {
	}
	
	public Node(Node parent, int state, int depth) {
		this._parent = parent;
		this._mrXState = state;
		this._detectiveStates = parent._detectiveStates;
		this._depth = depth;
		
	}
	
	/**
	 * Konstruktor für MrX (MAX-Node)
	 * @param parent Parent des Nodes
	 * @param state Node-Index 
	 * @param depth Tiefe in der Minimax-Suche
	 * @param detective Liste mit den Detective AIDs
	 */
	public Node(Node parent, Integer state, int depth, List<AID> detective) {
		this._parent = parent;
		this._mrXState = parent._mrXState;
		
		List<AID> detectives = Brain.getEnemyAIDs();
		for(AID aid : detectives){
			this._detectiveStates.put(aid, parent._detectiveStates.get(aid));
		}
		
		for(AID aid : detective){
			this._detectiveStates.put(aid, state);
		}
		
		this._depth = depth;
	}
	
	/**
	 * Konstruktor für Detective (MIN-Node)
	 * @param parent Parent des Nodes
	 * @param state Node-Index 
	 * @param depth Tiefe in der Minimax-Suche
	 * @param detective AID des Detectives
	 */
	public Node(Node parent, Integer state, int depth, AID detective) {
		this._parent = parent;
		this._mrXState = parent._mrXState;
		List<AID> detectives = Brain.getEnemyAIDs();
		for(AID aid : detectives){
			if(aid.equals(detective)){
				this._detectiveStates.put(detective, state);
			}else{
				this._detectiveStates.put(aid, parent._detectiveStates.get(aid));
			}
		}
		
		this._depth = depth;
	}

	public String toString() {
		String presentationString = "";
		for(int i = this._mrXState + _action; i > 0; i--) {
			if(i <= _action) {
				presentationString += "A";
			} else {
				presentationString += "X";
			}
			
		}
		
		return presentationString;
	}
	
	public boolean isTerminalNode() {
		return this._terminalNode;
	}
	
	public int getEnemyState(AID aid){
		return _detectiveStates.get(aid);
	}
	
}
